<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class OperationLog extends Model
{
    protected $fillable = [
        'user_id',
        'user_name',
        'user_ip',
        'user_agent',
        'session_id',
        'operation_type',
        'module_name',
        'action_name',
        'description',
        'target_model',
        'target_id',
        'target_name',
        'old_data',
        'new_data',
        'changed_fields',
        'status',
        'error_message',
        'error_details',
        'business_type',
        'business_id',
        'business_context',
        'severity',
        'requires_audit',
        'is_sensitive',
        'audit_status',
        'device_type',
        'browser',
        'os',
        'execution_time',
        'memory_usage',
        'db_queries_count',
        'parent_operation_id',
        'related_operations',
        'metadata',
        'notes'
    ];

    protected $casts = [
        'old_data' => 'array',
        'new_data' => 'array',
        'changed_fields' => 'array',
        'error_details' => 'array',
        'business_context' => 'array',
        'requires_audit' => 'boolean',
        'is_sensitive' => 'boolean',
        'execution_time' => 'decimal:3',
        'related_operations' => 'array',
        'metadata' => 'array',
    ];

    // 状态常量
    const STATUS_SUCCESS = 'success';
    const STATUS_FAILED = 'failed';
    const STATUS_PARTIAL = 'partial';

    // 严重程度常量
    const SEVERITY_LOW = 'low';
    const SEVERITY_MEDIUM = 'medium';
    const SEVERITY_HIGH = 'high';
    const SEVERITY_CRITICAL = 'critical';

    // 操作类型常量
    const OPERATION_CREATE = 'create';
    const OPERATION_UPDATE = 'update';
    const OPERATION_DELETE = 'delete';
    const OPERATION_READ = 'read';
    const OPERATION_LOGIN = 'login';
    const OPERATION_LOGOUT = 'logout';
    const OPERATION_EXPORT = 'export';
    const OPERATION_IMPORT = 'import';
    const OPERATION_UPLOAD = 'upload';
    const OPERATION_DOWNLOAD = 'download';

    /**
     * 获取关联用户
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * 获取父操作
     */
    public function parentOperation(): BelongsTo
    {
        return $this->belongsTo(OperationLog::class, 'parent_operation_id');
    }

    /**
     * 获取子操作
     */
    public function childOperations()
    {
        return $this->hasMany(OperationLog::class, 'parent_operation_id');
    }

    /**
     * 获取状态标签
     */
    public function getStatusLabelAttribute(): string
    {
        return match($this->status) {
            self::STATUS_SUCCESS => '成功',
            self::STATUS_FAILED => '失败',
            self::STATUS_PARTIAL => '部分成功',
            default => '未知'
        };
    }

    /**
     * 获取严重程度标签
     */
    public function getSeverityLabelAttribute(): string
    {
        return match($this->severity) {
            self::SEVERITY_LOW => '低',
            self::SEVERITY_MEDIUM => '中',
            self::SEVERITY_HIGH => '高',
            self::SEVERITY_CRITICAL => '严重',
            default => '未知'
        };
    }

    /**
     * 获取操作类型标签
     */
    public function getOperationTypeLabelAttribute(): string
    {
        return match($this->operation_type) {
            self::OPERATION_CREATE => '创建',
            self::OPERATION_UPDATE => '更新',
            self::OPERATION_DELETE => '删除',
            self::OPERATION_READ => '查看',
            self::OPERATION_LOGIN => '登录',
            self::OPERATION_LOGOUT => '登出',
            self::OPERATION_EXPORT => '导出',
            self::OPERATION_IMPORT => '导入',
            self::OPERATION_UPLOAD => '上传',
            self::OPERATION_DOWNLOAD => '下载',
            default => '未知操作'
        };
    }

    /**
     * 获取执行时间格式化字符串
     */
    public function getExecutionTimeFormattedAttribute(): string
    {
        if (!$this->execution_time) {
            return '-';
        }

        if ($this->execution_time < 1) {
            return round($this->execution_time * 1000, 2) . 'ms';
        }

        return round($this->execution_time, 2) . 's';
    }

    /**
     * 检查是否需要审计
     */
    public function requiresAudit(): bool
    {
        return $this->requires_audit;
    }

    /**
     * 检查是否为敏感操作
     */
    public function isSensitive(): bool
    {
        return $this->is_sensitive;
    }

    /**
     * 范围查询：按用户筛选
     */
    public function scopeByUser($query, int $userId)
    {
        return $query->where('user_id', $userId);
    }

    /**
     * 范围查询：按操作类型筛选
     */
    public function scopeByOperationType($query, string $operationType)
    {
        return $query->where('operation_type', $operationType);
    }

    /**
     * 范围查询：按模块筛选
     */
    public function scopeByModule($query, string $moduleName)
    {
        return $query->where('module_name', $moduleName);
    }

    /**
     * 范围查询：按状态筛选
     */
    public function scopeByStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 范围查询：按严重程度筛选
     */
    public function scopeBySeverity($query, string $severity)
    {
        return $query->where('severity', $severity);
    }

    /**
     * 范围查询：需要审计的操作
     */
    public function scopeRequiresAudit($query)
    {
        return $query->where('requires_audit', true);
    }

    /**
     * 范围查询：敏感操作
     */
    public function scopeSensitive($query)
    {
        return $query->where('is_sensitive', true);
    }

    /**
     * 范围查询：按时间范围筛选
     */
    public function scopeByDateRange($query, string $startDate, string $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    /**
     * 范围查询：按目标对象筛选
     */
    public function scopeByTarget($query, string $targetModel, int $targetId)
    {
        return $query->where('target_model', $targetModel)->where('target_id', $targetId);
    }

    /**
     * 获取变更字段的可读描述
     */
    public function getChangedFieldsDescription(): string
    {
        if (!$this->changed_fields) {
            return '无变更';
        }

        $descriptions = [];
        foreach ($this->changed_fields as $field => $change) {
            if (is_array($change) && isset($change['old']) && isset($change['new'])) {
                $oldValue = $this->formatValue($change['old']);
                $newValue = $this->formatValue($change['new']);
                $descriptions[] = "{$field}: {$oldValue} → {$newValue}";
            } else {
                $descriptions[] = $field;
            }
        }

        return implode('; ', $descriptions);
    }

    /**
     * 格式化字段值用于显示
     */
    private function formatValue($value): string
    {
        if (is_null($value)) {
            return 'null';
        }

        if (is_bool($value)) {
            return $value ? 'true' : 'false';
        }

        if (is_array($value)) {
            return '数组(' . count($value) . '项)';
        }

        if (is_string($value) && strlen($value) > 50) {
            return substr($value, 0, 47) . '...';
        }

        return (string) $value;
    }

    /**
     * 统计操作日志
     */
    public static function getOperationStats(string $startDate = null, string $endDate = null): array
    {
        $query = self::query();

        if ($startDate && $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate]);
        }

        return [
            'total_operations' => $query->count(),
            'successful_operations' => (clone $query)->where('status', 'success')->count(),
            'failed_operations' => (clone $query)->where('status', 'failed')->count(),
            'sensitive_operations' => (clone $query)->where('is_sensitive', true)->count(),
            'audit_required_operations' => (clone $query)->where('requires_audit', true)->count(),
            'unique_users' => (clone $query)->distinct('user_id')->count('user_id'),
            'avg_execution_time' => (clone $query)->avg('execution_time'),
        ];
    }
}
